home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 January / macformat-033.iso / mac / Shareware City / Developers / ABox.v1.8 / CPlus Files / ABSlide.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-23  |  15.8 KB  |  678 lines  |  [TEXT/MMCC]

  1. /*    
  2.     Copyright © 1991-1995 by TopSoft Inc.  All rights reserved.
  3.  
  4.     You may distribute this file under the terms of the TopSoft
  5.     Artistic License, accompanying this package.
  6.     
  7.     This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
  8.     See the Modification History for more details.
  9.  
  10. Product
  11.     About Box
  12.  
  13. FILE
  14.     ABSlide.c
  15.  
  16. NAME
  17.     ABSlide.c, part of the ABox project source code,
  18.     responsible for handling the AboutBox slide class stuff.
  19.  
  20. DESCRIPTION
  21.     This file contains defines for the about box modules.
  22.     
  23. DEVELOPED BY
  24.     George (ty) Tempel                netromancr@aol.com
  25.     All code in this file, and its associated header file was
  26.     Created by George (ty) Tempel in connection with the TopSoft, Inc.
  27.     "FilterTop" application development, except where noted.
  28.  
  29. CARETAKER - George (ty) Tempel <netromancr@aol.com>
  30.      Please consult this person for any changes or suggestions to this file.
  31.  
  32. MODIFICATION HISTORY
  33.  
  34.     dd mmm yy    -    xxx    -    patchxx: description of patch
  35.     9 June 94    -    ty    -    Initial Version Created
  36.     20-july-94    -    ty    -    initial version released
  37.     26-apr-95    -    ty    -    1.0.7--fixed handling of return type from
  38.                                 res->Event() within ForEach()
  39.     23-may-95    -    ty    -    changes for compatibility with the CodeWarrior CW6
  40.                             release and the associated Universal Headers from Apple:
  41.                             most methods that returned references now have "Ref" at
  42.                             the end of their methods names to prevent possible collisions
  43.                             with datatypes and classes of the same name (older versions
  44.                             of the compiler didn't have a problem with this).
  45.  
  46. */
  47.  
  48. /*===========================================================================*/
  49.  
  50. /*======= Segmentation directives ========*/
  51.  
  52. #ifdef USE_MANUAL_SEGMENTATION
  53. #pragma segment ty
  54. #endif
  55.  
  56. /*============ Header files ==============*/
  57.     
  58. #include     "ABSlide.h"
  59. #include    "ABResource.h"
  60.  
  61. #include    "ABPict.h"
  62. #include    "ABText.h"
  63. #include    "ABStr.h"
  64. #include    "ABSound.h"
  65.  
  66.  
  67. /*=============== Globals ================*/
  68.  
  69. /*================ CODE ==================*/
  70.  
  71.  
  72. /*=============================== ABSlide::ABSlide ================================*/
  73. ABSlide::ABSlide(void)
  74. {
  75.     this->Resources() = new ABLinkedList;
  76.     this->SlideNumber() = 0;
  77.     this->Initialized() = false;
  78. } // end ABSlide
  79.  
  80.  
  81.  
  82. /*=============================== ABSlide::~ABSlide ================================*/
  83. ABSlide::~ABSlide(void)
  84. {
  85.     this->ResetResources();
  86.  
  87. } // end ~ABSlide
  88.  
  89.  
  90.  
  91. /*=============================== ABSlide::ResetResources ================================*/
  92. void
  93. ABSlide::ResetResources(void)
  94. {
  95.     if (this->HasResources())
  96.     {
  97.         delete this->Resources();
  98.         this->Resources() = NULL;
  99.     }
  100. } // end ResetResources
  101.  
  102.  
  103.  
  104. /*=============================== ABSlide::GetProperty ================================*/
  105. OSErr    ABSlide::GetProperty(ABProperty prop, 
  106.                                 void *ptr, 
  107.                                 long *ptrSize)
  108. {
  109.     OSErr    error = noErr;
  110.     long    pSize;
  111.     
  112.     //    begin here...
  113.     
  114.     if (!ptr)
  115.         return kABPropertyNullStorage;
  116.     
  117.     switch (prop)
  118.     {
  119.         case    kABSlideNumber:
  120.                     (*(short *)ptr) = this->GetSlideNumber();
  121.                     pSize = kABSlideNumberSize;
  122.                     break;
  123.         case    kABSlideIndex:
  124.                     (*(ABIndex *)ptr) = this->Ordinal();
  125.                     pSize = kABSlideIndexSize;
  126.                     break;
  127.         case    kABSlideNumberOfElements:
  128.                     if (this->HasResources())
  129.                         (*(ABListCount *)ptr) = this->Resources()->Count();
  130.                     else
  131.                         (*(ABListCount *)ptr) = 0;
  132.                     pSize = kABSlideNumberOfElementsSize;
  133.         default:
  134.                     error = kABSlideSuperProperties::GetProperty(prop, ptr, ptrSize);
  135.                     break;
  136.     } // end switch block
  137.     
  138.     if (ptrSize && !error)
  139.         *ptrSize = pSize;
  140.     return error;
  141.     
  142. } // end GetProperty
  143.  
  144.  
  145.  
  146. /*=============================== ABSlide::SetProperty ================================*/
  147. OSErr    ABSlide::SetProperty(ABProperty prop, 
  148.                                 void *ptr, 
  149.                                 long ptrSize)
  150. {
  151.     OSErr    error = noErr;
  152.     
  153.     //    begin here...
  154.     
  155.     if (!ptr)
  156.         return kABPropertyNullStorage;
  157.     
  158.     switch (prop)
  159.     {
  160.         case    kABSlideNumber:
  161.                     this->SlideNumber() = (*(short *)ptr);
  162.                     break;
  163.         case    kABSlideNumberOfElements:
  164.                     error = kABPropertyReadOnly;
  165.                     break;
  166.         default:
  167.                     error = kABSlideSuperProperties::SetProperty(prop, ptr, ptrSize);
  168.                     break;
  169.     } // end switch block
  170.     
  171.     return error;
  172.     
  173. } // end SetProperty
  174.  
  175.  
  176.  
  177.  
  178.  
  179. /*=============================== ABSlide::InitializeObject ================================*/
  180. OSErr    ABSlide::InitializeObject(void)
  181. {
  182.     OSErr        error = noErr;
  183.     
  184.     ABResource    *res;
  185.     short        resID = this->GetSlideNumber();
  186.     
  187.     //    begin here...
  188.     //
  189.     //    attempt to load each of the resources we'd
  190.     //    be interested in for the slide. The caller may
  191.     //    have already added some to our list, so we'll
  192.     //    concern ourselves with appending to the list.
  193.     //
  194.     if (this->IsInitialized())
  195.         return noErr;
  196.  
  197.     res = new ABPict;
  198.     if (res)
  199.     {
  200.         error = res->SetProperty (kABResourceResID, &resID, kABResourceResIDSize);
  201.         if (res->CheckFile(NULL))
  202.         {
  203.             error = this->AddResource(res);
  204.         } else {
  205.             delete res;
  206.         } // end if block
  207.     } // end if block
  208.     
  209.     
  210.     res = new ABText;
  211.     if (res)
  212.     {
  213.         error = res->SetProperty (kABResourceResID, &resID, kABResourceResIDSize);
  214.         if (res->CheckFile(NULL))
  215.         {
  216.             error = this->AddResource(res);
  217.         } else {
  218.             delete res;
  219.         } // end if block
  220.     } // end if block
  221.     
  222.     
  223.     res = new ABSound;
  224.     if (res)
  225.     {
  226.         error = res->SetProperty (kABResourceResID, &resID, kABResourceResIDSize);
  227.         if (res->CheckFile(NULL))
  228.         {
  229.             error = this->AddResource(res);
  230.         } else {
  231.             delete res;
  232.         } // end if block
  233.     } // end if block
  234.     
  235.     
  236.     res = new ABStr;
  237.     if (res)
  238.     {
  239.         error = res->SetProperty (kABResourceResID, &resID, kABResourceResIDSize);
  240.         if (res->CheckFile(NULL))
  241.         {
  242.             error = this->AddResource(res);
  243.         } else {
  244.             delete res;
  245.         } // end if block
  246.     } // end if block
  247.     
  248.     this->Initialized() = true;
  249.     
  250.     return error;
  251.     
  252. } // end InitializeObject
  253.  
  254.  
  255.  
  256.  
  257. /*=============================== ABSlide::ForEach ================================*/
  258. //
  259. //    ForEach is an internal method to do some action/method for each
  260. //    list member.
  261. //
  262. OSErr    ABSlide::ForEach (ABMessage message, void *data)
  263. {
  264.     OSErr        error = noErr;
  265.     long        i;
  266.     long        limit;
  267.     ABResource    *res = NULL;
  268.     
  269.     //    begin here...
  270.     
  271.     if (this->IsntInitialized() && (message != kABMessageStop))
  272.         error = this->InitializeObject();
  273.     
  274.     if (this->HasResources() && !error)
  275.         limit = this->Resources()->Count();
  276.     else
  277.         return error;
  278.     
  279.     if (limit < 1)
  280.     {
  281.         error = noErr;
  282.     } else {
  283.         for (i = 1; i <= limit; ++i)
  284.         {
  285.             Boolean handled = false;
  286.             
  287.             res = (ABResource *)(this->Resources()->NthLink(i));
  288.             if (res)
  289.             {
  290.                 switch (message)
  291.                 {
  292.                     case    kABMessageDraw:
  293.                             error = res->Draw((WindowPtr)data);
  294.                             break;
  295.                     case    kABMessageUpdate:
  296.                             error = res->Update((WindowPtr)data);
  297.                             break;
  298.                     case    kABMessageEvent:
  299.                             handled = res->Event((EventRecord *)data);
  300.                             break;
  301.                     case    kABMessageStop:
  302.                             error = res->Stop();
  303.                             break;
  304.                 } // end switch block
  305.             } else {
  306.                 //    couldn't locate the ith resource for this slide! yikes!
  307.                 //
  308.                 res = NULL;
  309.             } // end if block
  310.         } // end for loop
  311.  
  312.     }
  313.     return error;
  314.     
  315. } // end ForEach()
  316.  
  317.  
  318.  
  319.  
  320. /*=============================== ABSlide::Draw ================================*/
  321. OSErr    ABSlide::Draw(WindowPtr window)
  322. {
  323.     return this->ForEach (kABMessageDraw, window);    
  324. } // end Draw
  325.  
  326.  
  327.  
  328.  
  329.  
  330. /*=============================== ABSlide::AddResource ================================*/
  331. OSErr    ABSlide::AddResource(ABResource *obj)
  332. {
  333.     OSErr        error = noErr;
  334.     short        resID = this->GetSlideNumber();
  335.     
  336.     //    begin here...
  337.     //
  338.     //    the intent here is to add the given object to the
  339.     //    list maintained by the slide. The object will be
  340.     //    given the same resource ID# as the slide.
  341.     //
  342.     if (obj && this->HasResources())
  343.     {
  344.         error = obj->SetProperty (kABResourceResID, &resID, kABSlideNumberSize);
  345.         this->Resources()->Append ((ABLink *)obj);
  346.     } else {
  347.         error = paramErr;
  348.     } // end if block
  349.     
  350.     return error;
  351.     
  352. } // end AddResource
  353.  
  354.  
  355.  
  356.  
  357.  
  358. /*=============================== ABSlide::DropResource ================================*/
  359. OSErr    ABSlide::DropResource(ABResource *obj)
  360. {
  361.     OSErr        error = noErr;
  362.  
  363.     //    begin here...
  364.     //
  365.     //    the intent here is to delete the given object to the
  366.     //    list maintained by the slide.
  367.     //
  368.     if (obj && this->HasResources())
  369.     {
  370.         this->Resources()->Detach ((ABLink *)(obj));
  371.     } else {
  372.         error = paramErr;
  373.     } // end if else block
  374.     
  375.     return error;
  376.     
  377. } // end DropResource
  378.  
  379.  
  380.  
  381.  
  382.  
  383. /*=============================== ABSlide::Update ================================*/
  384. OSErr    ABSlide::Update(WindowPtr window)
  385. {
  386.     return this->ForEach (kABMessageUpdate, window);    
  387. } // end Update
  388.  
  389.  
  390.  
  391.  
  392. /*=============================== ABSlide::Event ================================*/
  393. Boolean    ABSlide::Event(EventRecord *eventRec)
  394. {
  395.     return (Boolean)this->ForEach (kABMessageEvent, eventRec);    
  396.     
  397. } // end Event
  398.  
  399.  
  400.  
  401. /*=============================== ABSlide::Stop ================================*/
  402. OSErr    ABSlide::Stop(void)
  403. {
  404.     return this->ForEach (kABMessageStop, NULL);    
  405. } // end Stop
  406.  
  407.  
  408.  
  409.  
  410. /*=============================== ABSlide::GetResourceOfType ================================*/
  411. ABResource    *ABSlide::GetResourceOfType(ResType type)
  412. {
  413.     ABResource    *rsrc;
  414.     ABIndex        i;
  415.     ABListCount    limit;
  416.     ResType        resType;
  417.     long        size = kABResourceResTypeSize;
  418.     OSErr        error = noErr;
  419.     
  420.     //    begin here...
  421.     if (this->IsntInitialized())
  422.         error = this->InitializeObject();
  423.     
  424.     
  425.     if (this->HasResources())
  426.         limit = this->Resources()->Count();
  427.     else
  428.         return NULL;
  429.     
  430.     for (i = 1; i <= limit; ++i)
  431.     {
  432.         rsrc = (ABResource *)(this->Resources()->NthLink(i));
  433.         if (!rsrc)
  434.             continue;
  435.         error = rsrc->GetProperty(kABResourceResType, &resType, &size);
  436.         if (!error && (resType == type))
  437.             return rsrc;
  438.     } // end for loop
  439.     
  440.     return NULL;
  441.     
  442. } // end GetResourceOfType
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449. /*=============================== ABSlide::Resize ===============================*/
  450. //
  451. //    this function will rearrange and resize the picture and the
  452. //    text fields that appear on a slide.
  453. //
  454. //    10-nov-93    -    ty    -    d25 changes to improve picture
  455. //                            placement
  456. //
  457. //    20-nov-93    -    ty    -    d26 changes to support the unification
  458. //                            of the slideField with the slideTitleField
  459. //                            to reduce the number of things on the screen
  460. //                            and to provide more room for slides if no
  461. //                            title's are present.
  462. //
  463. //    is called by:
  464. //
  465. OSErr    ABSlide::Resize (Rect const *field)
  466. {
  467.     OSErr                    error = noErr;
  468.  
  469.     ABResource                *pict;
  470.     ABResource                *text;
  471.     ABResource                *title;
  472.     
  473.     Rect                    area;
  474.     Rect                    pictRect;
  475.     Rect                    textRect;
  476.     Rect                    titleRect;
  477.                 
  478.     short                    fieldWidth,
  479.                             fieldHeight;
  480.     
  481.     short                    offsetX,
  482.                             offsetY;
  483.     
  484.     SlideElementPositions    position = leftOrRight;
  485.     
  486.     PicHandle                pictureH;
  487.     
  488.     short                    fontHeight;            //    1.0a9p8 ty...added
  489.     short                    maximumTitleHeight;    //    1.0a9p8 ty...added
  490.     
  491.     
  492.     //    begin here...    
  493.  
  494.     if (this->IsntInitialized())
  495.         error = this->InitializeObject();
  496.     
  497.     if (this->DoesntHaveResources())
  498.         return paramErr;
  499.     
  500.     if (!field)
  501.         return paramErr;
  502.     else
  503.         area = *field;
  504.         
  505.     //    erase the field...
  506.     error = this->EraseFrame(area);
  507.     
  508.     //    calculation of fontHeight and maximumTitleHeight for better box sizing
  509.     fontHeight = ABUFonts::FindFontHeight();
  510.     maximumTitleHeight = 2 * fontHeight;
  511.     
  512.     //    get the slide elements we care about
  513.     pict = this->GetResourceOfType(kABPictResource);
  514.     text = this->GetResourceOfType(kABTextResource);
  515.     title = this->GetResourceOfType(kABStringResource);
  516.  
  517.     //    check to see if we should even bother
  518.     if (!(pict || text || title))
  519.         return error;
  520.  
  521.     titleRect = pictRect = textRect = area;
  522.     if (title)
  523.     {
  524.         titleRect.top = titleRect.bottom - maximumTitleHeight;
  525.         area.bottom = pictRect.bottom = textRect.bottom = titleRect.top - 2*kABdialogSpacing;
  526.     } // end if block
  527.     
  528.     //    now save the modified sub areas into the proper
  529.     //    slide elements
  530.     if (pict)
  531.         error = pict->SetProperty(kABObjectRect, &pictRect, kABObjectRectSize);
  532.     if (text)
  533.         error = text->SetProperty(kABObjectRect, &textRect, kABObjectRectSize);
  534.     if (title)
  535.         error = title->SetProperty(kABObjectRect, &titleRect, kABObjectRectSize);
  536.     
  537.     //    now see if things need to be rearranged
  538.     if (pict) 
  539.     {
  540.         //    now get the picture information
  541.         error = pict->GetProperty(kABResourceHandle, &pictureH, NULL);
  542.         
  543.         if (pictureH && !error) 
  544.         {
  545.             //    1.0a7 ty...the two following statements were rewritten to utilize (*pictureH)->picFrame
  546.             //                rather than the information from GetPictInfo.
  547.             //
  548.             ::HLock ((Handle)pictureH);
  549.             pictRect.right = pictRect.left + ((*pictureH)->picFrame.right - (*pictureH)->picFrame.left);
  550.             pictRect.bottom = pictRect.top + ((*pictureH)->picFrame.bottom - (*pictureH)->picFrame.top);
  551.             ::HUnlock ((Handle)pictureH);
  552.             
  553.             //    decide what the aspect ratio is and 
  554.             //    where it should fit in the field.
  555.             //
  556.             if ((pictRect.right - pictRect.left) < (pictRect.bottom - pictRect.top)) 
  557.             {
  558.                 position = leftOrRight;
  559.             } else {
  560.                 position = aboveOrBelow;
  561.             }    //    end if else block
  562.         
  563.         } else {
  564.             //    there is a problem with the handle,
  565.             //    so the picture element is basically useless to us.
  566.             pict = NULL;
  567.             pictRect.right = pictRect.top = pictRect.left = pictRect.bottom = 0;
  568.         } // end if block
  569.     } // end if (pict)
  570.     
  571.     //    if the picture is smaller than our field then we'll just center
  572.     //    and display the picture; if the picture is larger than the field
  573.     //    we'll scale it.
  574.     //
  575.     
  576.     fieldWidth = area.right - area.left;
  577.     fieldHeight = area.bottom - area.top;
  578.     
  579.     //    if there are both text and pict objects then we
  580.     //    need to arrange them properly on the field. If there
  581.     //    is only a pict, then it will be centered in the field.
  582.     //    If there is only a text, then it already has its field
  583.     // 
  584.     if (text && pict) 
  585.     {
  586.         if (position == aboveOrBelow) 
  587.         {
  588.             //Rect    box;
  589.             
  590.             //    make enough room for the text area below...no additional
  591.             //    reduction is necessary
  592.             
  593.             //box = *field;
  594.             //box.bottom -= kABscrollBarMinLength;
  595.             //
  596.             //    addition of the scroll-bar area to the right
  597.             //    side to allow the pict to occupy the entire area
  598.             //    left to right, and move the bottom up to allow for
  599.             //    the minimum size text field possible.
  600.             //
  601.             area.right += kABscrollBarWidth;
  602.             area.bottom -= kABscrollBarMinLength;
  603.             error = this->ScaleRectToFit (pictRect, area, 1.0);
  604.             //    restore the field geometry
  605.             area.bottom += kABscrollBarMinLength;
  606.             area.right -= kABscrollBarWidth;
  607.             
  608.             //    use the space below the picture as the text rect
  609.             //    and center the picture left/right
  610.             //
  611.             offsetX = (fieldWidth - (pictRect.right - pictRect.left))/2;
  612.             offsetY = 0;
  613.     
  614.         } else {
  615.             error = this->ScaleRectToFit (pictRect, area, kABreduceFactor);
  616.             //    use the space to the right of the picture as the textRect
  617.             //    and center the graphic top/bottom on the left.
  618.             //
  619.             offsetX = 0;
  620.             offsetY = (fieldHeight - (pictRect.bottom - pictRect.top))/2;
  621.  
  622.         }    //    end if block
  623.     } else if (pict && !text) {
  624.         //    addition of the scroll-bar area to the right
  625.         //    side to allow the pict to occupy the entire area,
  626.         //    both left to right and top to bottom
  627.         //
  628.         pictRect.right += kABscrollBarWidth;
  629.         area.right += kABscrollBarWidth;
  630.         error = this->ScaleRectToFit (pictRect, area, 1.0);
  631.         area.right -= kABscrollBarWidth;
  632.         
  633.         //    there is only a graphic, so we should center the graphic top/bottom 
  634.         //    and left/right in the field.
  635.         //
  636.         offsetX = (fieldWidth - (pictRect.right - pictRect.left))/2;
  637.         offsetY = (fieldHeight - (pictRect.bottom - pictRect.top))/2;
  638.         
  639.     } else if (text && !pict) {
  640.         //    there is only a text field, so let it occupy the whole field
  641.         //
  642.         offsetX = offsetY = 0;
  643.     
  644.     } // end if....elseif block
  645.     
  646.  
  647.     //    move the picture rect...
  648.     //
  649.     if (pict)
  650.         ::OffsetRect (&pictRect, offsetX, offsetY);
  651.  
  652.     //    and now size the text rect accordingly...
  653.     if (text)
  654.     {
  655.         if (offsetX > 0)
  656.             textRect.top = pictRect.bottom + kABdialogSpacing;
  657.         if (offsetY > 0)
  658.             textRect.left = pictRect.right + kABdialogSpacing;
  659.         error = text->SetProperty(kABObjectRect, &textRect, kABObjectRectSize);
  660.     } // end if block
  661.     
  662.     //    now save the modified sub areas into the proper
  663.     //    slide elements
  664.     if (pict)
  665.         error = pict->SetProperty(kABObjectRect, &pictRect, kABObjectRectSize);
  666.     if (title)
  667.         error = title->SetProperty(kABObjectRect, &titleRect, kABObjectRectSize);
  668.     
  669.     //    we're done!
  670.     return error;
  671.     
  672. }    //    end of function Resize()
  673.  
  674.  
  675.  
  676. //    end of file
  677.  
  678.